package com.simoniu.spt.course.service.impl;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.simoniu.spt.course.entity.BaseEntity;
import com.simoniu.spt.course.repository.BaseRepository;
import com.simoniu.spt.course.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import javax.transaction.Transactional;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Optional;

public class BaseServiceImpl<T extends BaseEntity, I extends Serializable, R extends BaseRepository<T, I>,M extends BaseMapper> implements BaseService<T, I, R, M> {

    @Autowired
    protected R dao;
    @Autowired
    protected M mapper;

    @Transactional
    @Override
    public int insertWithMybatis(T obj) {
        return mapper.insert(obj);
    }

    @Transactional
    @Override
    public int deleteByIdWithMybatis(I id) {
        return mapper.deleteById(id);
    }

    @Transactional
    @Override
    public int updateByIdWithMybatis(T obj) {
        return mapper.updateById(obj);
    }

    @Transactional
    @Override
    public T selectByIdWithMybatis(I id) {
        return (T)mapper.selectById(id);
    }

    @Transactional
    @Override
    public List<T> selectListWithMybatis(Wrapper<T> wrapper) {
        return mapper.selectList(wrapper);
    }

    @Transactional
    @Override
    public List<T> findAll() {
        return dao.findAll();
    }


    @Override
    public List<T> findAll(Example<T> example) {
        return dao.findAll(example);
    }

    @Transactional
    @Override
    public T getOne(I id) {
        return dao.getOne(id);
    }

    @Transactional
    @Override
    public T getOne(Specification<T> var1) {
        Optional<T> option  = dao.findOne(var1);
        if(option.isPresent()){
            return (T)dao.findOne(var1).get();
        }else{
            return null;
        }
    }

    @Transactional
    @Override
    public Page<T> findAllByPager(Pageable pageable) {
        return dao.findAll(pageable);
    }

    @Transactional(rollbackOn = Exception.class)
    @Override
    public T save(T obj) {
        System.out.println("开始执行BaseServiceImpl-->save()");
        Date d = new Date();
        DateTime dt = DateTime.of(d);
        obj.setCreateTime(dt.toString("yyyy-MM-dd HH:mm:ss"));
        System.out.println("createTime is :"+obj.getCreateTime());
        obj.setModifyTime(dt.toString("yyyy-MM-dd HH:mm:ss"));
        obj.setFlag(false);

        return dao.save(obj);

    }

    @Transactional(rollbackOn = Exception.class)
    @Override
    public T update(T obj) {

        Date d = new Date();
        DateTime dt = DateTime.of(d);
        obj.setModifyTime(dt.toString("yyyy-MM-dd HH:mm:ss"));
        obj.setVersion(obj.getVersion()+1);
        return dao.save(obj);

    }

    @Transactional(rollbackOn = Exception.class)
    @Override
    public void deleteById(I id) {
        Optional<T> obj = dao.findById(id);
        T target = obj.get();
        target.setFlag(true);
        this.update(target);
        //dao.deleteById(id); //注意这个deleteById(id)是真正的物理删除。
    }

    @Override
    public List<T> saveList(List<T> list) {
        //设置插入时间
        for(T obj: list){
            Date d = new Date();
            DateTime dt = DateTime.of(d);
            obj.setCreateTime(dt.toString("yyyy-MM-dd HH:mm:ss"));
            obj.setFlag(true);
        }
        return dao.saveAll(list);
    }

    @Override
    public void batchDelete(List<T> list) {
        dao.deleteInBatch(list);
    }
}
